﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework.Input;
using ProjetCom.Model.CasseBriques;
using ProjetCom.Vue;
using ProjetCom.Model.Template;
using ProjetCom.Model.Pong;

namespace ProjetCom.Ctrl
{
    class CtrlPong : CtrlTemplate
    {
        private List<Raquette> m_BarrePlayer;
        private List<Raquette> m_BarreOther;
        private Balle m_Balle;
        private List<Element> m_Elements;



        public List<Element> Elements
        {
            get { return m_Elements; }
        }

        public List<Raquette> BarrePlayer
        {
            get { return m_BarrePlayer; }
        }
        public List<Raquette> BarreOther
        {
            get { return m_BarreOther; }
        }
        public Balle BarreBalle
        {
            get { return m_Balle; }
        }

        public CtrlPong(IServiceProvider p_serviceProvider, int p_score) :
            base(p_serviceProvider, p_score)
        {
            m_Level = new LevelPong(p_serviceProvider, this);
            m_BarrePlayer = new List<Raquette>();
            m_BarreOther = new List<Raquette>();
            m_Elements = new List<Element>();

            m_BarrePlayer.Add(new Raquette(0, 4, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 5, Raquette.DirectionBare.left));
            /*
            m_BarrePlayer.Add(new Raquette(0, 6, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 7, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 8, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 9, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 10, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 0, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 1, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 2, Raquette.DirectionBare.left));
            m_BarrePlayer.Add(new Raquette(0, 3, Raquette.DirectionBare.left));
             */

            m_BarreOther.Add(new Raquette(19, 4, Raquette.DirectionBare.right));
            m_BarreOther.Add(new Raquette(19, 5, Raquette.DirectionBare.right));

            m_Balle = new Balle(1, 5, 140, 70);

            m_Elements.Add(m_Balle);
            m_Elements.AddRange(m_BarrePlayer);
            m_Elements.AddRange(m_BarreOther);
        }

        public override void Update(Microsoft.Xna.Framework.GameTime _gameTime)
        {
                m_Balle.Update(_gameTime);
                if (!TestCollisionBalleBarre())
                {
                    TestSortieBalle();
                }
                else
                {
                    m_Score += 50;
                    m_Balle.StepH += (int)(m_Balle.StepH * 0.015);
                    m_Balle.StepV += (int)(m_Balle.StepV * 0.015);
                }

        }

        private void TestSortieBalle()
        {

            if (m_Balle.X <= 0)
            {
                ReturnMenu = true;
            }
            else if ((m_Balle.X + Element.Width) >= 1280)
            {
                m_Score += 1000;
                ReturnMenu = true;
            }

            if (m_Balle.Y <= 0)
            {
                m_Balle.Y = 1;
                m_Balle.Collision(Element.CoteCollision.top);
            }
            else if ((m_Balle.Y + Element.Height) >= 720)
            {
                m_Balle.Y = 720 - Element.Height;
                m_Balle.Collision(Element.CoteCollision.bottom);
            }
        }

        public bool TestCollisionBalleBarre()
        {
            int YBottomFirst = (int)(m_BarreOther[0].Y + Element.Width);

            foreach (Raquette raquette in m_BarrePlayer)
            {
                if (raquette.EnterCollision(m_Balle) != Element.CoteCollision.none)
                {
                    m_Balle.Collision(Element.CoteCollision.left);
                    m_Balle.X = Element.Width;
                    return true;
                }
            }
            foreach (Raquette raquette in m_BarreOther)
            {
                if (raquette.EnterCollision(m_Balle) != Element.CoteCollision.none)
                {
                    m_Balle.Collision(Element.CoteCollision.right);
                    m_Balle.X = 1280 - Element.Height*2;
                    return true;
                }
            }

            if (m_Balle.Y > Element.Width && m_Balle.Y < 1280 - Element.Height)
            {
                // on met a jour la barre de l'adversaire selon la position de la balle
                if (m_Balle.Centre.Y < YBottomFirst)
                {
                    int changeValue = new Random().Next(30) % (YBottomFirst - m_Balle.Centre.Y);
                    foreach (Barre barre in m_BarreOther)
                    {
                        barre.Y -= changeValue;
                    }
                }
                else if (m_Balle.Centre.Y > YBottomFirst)
                {
                    int changeValue = new Random().Next(30);
                    foreach (Barre barre in m_BarreOther)
                    {
                        barre.Y += changeValue;
                    }
                }
            }

            return false;
        }

        public override void EventClavier()
        {
            // Get input state.
            KeyboardState keyboardState = Keyboard.GetState();

            if (!m_BarrePlayer.Exists(new Predicate<Barre>(delegate(Barre b) { return !b.CanMooveTop(); })) && keyboardState.IsKeyDown(Keys.Up))
            {
                foreach (Barre barre in m_BarrePlayer)
                {
                        barre.MooveTop();
                }
            }
            
            else if (!m_BarrePlayer.Exists(new Predicate<Barre>(delegate(Barre b) { return !b.CanMooveBottom(); })) && keyboardState.IsKeyDown(Keys.Down))
            {
                foreach (Barre barre in m_BarrePlayer)
                {
                        barre.MooveBottom();
                }
            }
        }
    }
}
